#include <iostream>
#include <set>
#include <cmath>
using namespace std;
template <typename Container>
void display(const Container &con)
{
    for (auto &elem : con)
    {
        cout << elem << "  ";
    }
    cout << endl;
}
class Point
{
public:
    Point(int x, int y)
        : _x(x), _y(y)
    {
    }
    friend struct CompairList;
    friend std::ostream &operator<<(std::ostream &os, const Point &rhs);
    friend bool operator<(const Point &lhs, const Point &rhs);
    friend struct less<Point>;

private:
    int _x;
    int _y;
};
namespace std{
//通过模板特化
template <>
struct less<Point>
{
    bool operator()(const Point & lsh,const Point & rhs)const{
        cout << "template<>" << endl;
        float lshs = hypot(lsh._x, lsh._y);
    float rhss = hypot(rhs._x, rhs._y);
    if (lshs < rhss)
    {
        return true;
    }
    else if (lshs == rhss)
    {
        if (lsh._x < rhs._x)
        {
            return true;
        }
        else if (lsh._x == rhs._x)
        {
            if (lsh._y < rhs._y)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            return false;
        }
    }
    else
    {
        return false;
    }
    }
};
}
//通过重载<的方法
bool operator<(const Point &lsh, const Point &rhs)
{
    cout << "operator <" << endl;
    float lshs = hypot(lsh._x, lsh._y);
    float rhss = hypot(rhs._x, rhs._y);
    if (lshs < rhss)
    {
        return true;
    }
    else if (lshs == rhss)
    {
        if (lsh._x < rhs._x)
        {
            return true;
        }
        else if (lsh._x == rhs._x)
        {
            if (lsh._y < rhs._y)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            return false;
        }
    }
    else
    {
        return false;
    }
}
//通过比较对象传入
struct CompairList
{
    bool operator()(const Point &lsh, const Point &rhs) const
    {
        cout << "struct CompairList" << endl;
        float lshs = hypot(lsh._x, lsh._y);
        float rhss = hypot(rhs._x, rhs._y);
        if (lshs < rhss)
        {
            return true;
        }
        else if (lshs == rhss)
        {
            if (lsh._x < rhs._x)
            {
                return true;
            }
            else if (lsh._x == rhs._x)
            {
                if (lsh._y < rhs._y)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }
        else
        {
            return false;
        }
    }
};
std::ostream &operator<<(std::ostream &os, const Point &rhs)
{
    os << "(" << rhs._x
       << ", " << rhs._y
       << ")";
    return os;
}

void test()
{
    set<Point> number =
        {
            Point(1, 2),
            Point(3, 4),
            Point(-1, 2),
            Point(3, 4),
            Point(0, 6),
        };
    display(number);
}
int main()
{
    test();
    return 0;
}
